﻿@using System.IO.Ports;
@using Windows.Devices.Bluetooth.Advertisement;
@using zy_simu.Data;
@using System.Text.Json;
@using System.IO;
@implements IDisposable;
@inject SimuCfg emu_cfg;
@inject BlazorWebViewReaction blazor_webview

<div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:20%; margin-right:5px"> 仿真器参数： </div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 模式： </div>
        <div class="btn-group" role="group" style="width:25%; margin-left:0px; margin-right:10px">
            <Button Icon="fas fa-code-compare" Color="@(emu_cfg.mon_mode == "串口" ? Color.Success:Color.Secondary)" OnClick='() => MonModeChanged("串口")' Size="Size.Small">串口</Button>
            <Button Icon="fas fa-satellite-dish" Color="@(emu_cfg.mon_mode == "蓝牙" ? Color.Success:Color.Secondary)" OnClick='() => MonModeChanged("蓝牙")' Size="Size.Small">蓝牙</Button>
        </div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 接口： </div>
        <div style="width:70%; margin-right:5px"> <Select Items='@((emu_cfg.mon_mode == "串口") ? serial_port_items : ble_port_items)' @bind-Value="emu_cfg.mon_port"></Select> </div>
    </div>

    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:28%; margin-right:5px"> M0设备：</div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 模式：</div>
        <div class="btn-group" role="group" style="width:40%; margin-left:0px; margin-right:5px">
            <Button Icon="fas fa-laptop-code" Color="@(emu_cfg.m0_mode == "关闭" ? Color.Success:Color.Secondary)" OnClick='() => M0ModeChanged("关闭")' Size="Size.Small">关闭</Button>
            <Button Icon="fas fa-laptop-code" Color="@(emu_cfg.m0_mode == "仿真" ? Color.Success:Color.Secondary)" OnClick='() => M0ModeChanged("仿真")' Size="Size.Small">仿真</Button>
            <Button Icon="fas fa-microchip" Color="@(emu_cfg.m0_mode == "外设" ? Color.Success:Color.Secondary)" OnClick='() => M0ModeChanged("外设")' Size="Size.Small">外设</Button>
        </div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 串口0：</div>
        <div style="width:35%; margin-right:5px"><Select IsDisabled='@(emu_cfg.m0_mode == "关闭")' Items="serial_port_items" TValue="string" OnSelectedItemChanged="(select) => OnM0PortItemChanged(0, select)" Value="emu_cfg.m0_port[0]"></Select></div>
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 串口1：</div>
        <div style="width:35%; margin-right:5px"><Select IsDisabled='@(emu_cfg.m0_mode == "关闭")' Items="serial_port_items" TValue="string" OnSelectedItemChanged="(select) => OnM0PortItemChanged(1, select)" Value="emu_cfg.m0_port[1]"></Select></div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 串口2：</div>
        <div style="width:35%; margin-right:5px"><Select IsDisabled='@(emu_cfg.m0_mode == "关闭")' Items="serial_port_items" TValue="string" OnSelectedItemChanged="(select) => OnM0PortItemChanged(2, select)" Value="emu_cfg.m0_port[2]"></Select></div>
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 串口3：</div>
        <div style="width:35%; margin-right:5px"><Select IsDisabled='@(emu_cfg.m0_mode == "关闭")' Items="serial_port_items" TValue="string" OnSelectedItemChanged="(select) => OnM0PortItemChanged(3, select)" Value="emu_cfg.m0_port[3]"></Select></div>
    </div>

    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:28%; margin-right:5px"> Cat1设备：</div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 模式：</div>
        <div class="btn-group" role="group" style="width:40%; margin-left:0px; margin-right:5px">
            <Button Icon="fas fa-laptop-code" Color="@(emu_cfg.cat1_mode == "关闭" ? Color.Success:Color.Secondary)" OnClick='() => Cat1ModeChanged("关闭")' Size="Size.Small">关闭</Button>
            <Button Icon="fas fa-laptop-code" Color="@(emu_cfg.cat1_mode == "仿真" ? Color.Success:Color.Secondary)" OnClick='() => Cat1ModeChanged("仿真")' Size="Size.Small">仿真</Button>
            <Button Icon="fas fa-microchip" Color="@(emu_cfg.cat1_mode == "外设" ? Color.Success:Color.Secondary)" OnClick='() => Cat1ModeChanged("外设")' Size="Size.Small">外设</Button>
        </div>
    </div>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 串口0：</div>
        <div style="width:35%; margin-right:5px"><Select IsDisabled='@(emu_cfg.cat1_mode == "关闭")' Items="serial_port_items" TValue="string" OnSelectedItemChanged="(select) => OnCat1PortItemChanged(0, select)" Value="emu_cfg.cat1_port[0]"></Select></div>
        <div style="width:2%; margin-right:5px"></div>
        <div style="width:13%; margin-right:5px"> 串口1：</div>
        <div style="width:35%; margin-right:5px"><Select IsDisabled='@(emu_cfg.cat1_mode == "关闭")' Items="serial_port_items" TValue="string" OnSelectedItemChanged="(select) => OnCat1PortItemChanged(1, select)" Value="emu_cfg.cat1_port[1]"></Select></div>
    </div>
    <Divider></Divider>
    <div style="display:flex; align-items: center; margin-bottom:5px">
        <div style="width:70%; margin-right:5px"></div>
        <div style="width:15%; margin-right:5px">
            <Button Color="Color.Primary" OnClick="OnSaveClick"><i class="fas fa-floppy-disk"></i>存储</Button>
        </div>
        <div style="width:15%; margin-right:5px">
            <Button @ref="button_close" Color="Color.Primary" OnClick="OnCloseClick"><i class="fas fa-xmark"></i>关闭</Button>
        </div>
    </div>

</div>

@code {
    [Parameter]
    public Button button_close { get; set; } = new();
    [Parameter]
    public DialogOption option { get; set; }

    public string emu_device = "md326";
    public string mcu_mode = "emulate";
    public string cat1_mode = "emulate";
    public string mcu_com = "";
    public string cat1_com = "";
    public string dbg_com = "";

    private readonly BluetoothLEAdvertisementWatcher advertisementWatcher = new BluetoothLEAdvertisementWatcher();

    // 仿真设备类型
    private SelectedItem[] device_items { get; set; } = new SelectedItem[] { new SelectedItem("", "无") { Active = true }, };
    // 仿真设备监控模式和接口
    private List<SelectedItem> mon_port_items { get; set; } = new();
    // C485智能模块运行模式和接口
    private List<SelectedItem> c485_port_items { get; set; } = new();
    // m0设备运行模式和接口
    private List<SelectedItem> m0_port_items { get; set; } = new();
    // cat1设备运行模式和接口
    private List<SelectedItem> cat1_port_items { get; set; } = new();

    // 枚举系统串口
    private List<SelectedItem> serial_port_items = new();
    private List<SelectedItem> GetSerialPortsList()
    {
        string[] s_ports = SerialPort.GetPortNames();
        List<SelectedItem> items = new();
        items.Add(new SelectedItem("关闭", "关闭"));
        items.Add(new SelectedItem("虚拟接口-1", "虚拟接口-1"));
        items.Add(new SelectedItem("虚拟接口-2", "虚拟接口-2"));
        foreach (string s in s_ports)
        {
            items.Add(new SelectedItem(s, s));
        }
        return items;
    }
    // 枚举扫描到的蓝牙设备
    private List<SelectedItem> ble_port_items = new();
    private void StartBleScan()
    {
        advertisementWatcher.ScanningMode = BluetoothLEScanningMode.Active;
        advertisementWatcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;
        advertisementWatcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;
        advertisementWatcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMicroseconds(5000);
        advertisementWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMicroseconds(2000);
        advertisementWatcher.Received += AdvertisementWatcher_Received;
        advertisementWatcher.Stopped += AdvertisementWatcher_Stopped;
        advertisementWatcher.Start();
    }
    private void StopBleScan()
    {
        if (advertisementWatcher.Status == BluetoothLEAdvertisementWatcherStatus.Started)
            advertisementWatcher.Stop();
    }
    private List<SelectedItem> GetBlePortsList()
    {
        ble_port_items.Clear();
        if (emu_cfg.mon_mode == "蓝牙")
            ble_port_items.Add(new SelectedItem(emu_cfg.mon_port, emu_cfg.mon_port+" - 上次的值"));
        StartBleScan();
        return ble_port_items;
    }
    private void AdvertisementWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
    {
        string name = args.Advertisement.LocalName;
        // string mac_value = args.BluetoothAddress.ToString("X");
        if (name != "")
            name = " - " + name;
        ulong mac_num = args.BluetoothAddress;
        string mac = "";
        for (int i = 0; i < 6; i++, mac_num = mac_num >> 8)
        {
            mac = ((byte)(mac_num & 0xff)).ToString("X")+":"+mac;
        }
        mac = mac[0..^1];
        // dispose the repeated data
        foreach (SelectedItem item in ble_port_items)
        {
            if (item.Value == mac)  // 重复
            {
                item.Text = mac + name; // name可能变化，修正name
                return;
            }
        }
        ble_port_items.Add(new SelectedItem(mac, mac + name));
        InvokeAsync(StateHasChanged);
    }
    private void AdvertisementWatcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)
    {
        //     Log.Info("AdvertisementWatcher_Stopped");
        //     Stopped?.Invoke(this, args);
    }

    // 监控模式变化
    private void MonModeChanged(string mode)
    {
        if (emu_cfg.mon_mode == mode) 
            return;

        if(mode != "")
        {
            emu_cfg.mon_mode = mode;
            emu_cfg.mon_port = "";
        }

        if (emu_cfg.mon_mode == "串口")
        {
            mon_port_items = GetSerialPortsList();
            StopBleScan();
        }
        else if (emu_cfg.mon_mode == "蓝牙")
        {
            mon_port_items = GetBlePortsList();
        }
        else // "模拟"
        {
            mon_port_items.Clear();
            mon_port_items.Add(new SelectedItem("", "无") { Active = true });
        }
    }
    // M0模式变化
    private void M0ModeChanged(string mode)
    {
        if (emu_cfg.m0_mode == mode)
            return;

        if (mode != "")
            emu_cfg.m0_mode = mode;
    }
    // Cat1模式变化
    private void Cat1ModeChanged(string mode)
    {
        if (emu_cfg.cat1_mode == mode)
            return;

        if (mode != "")
            emu_cfg.cat1_mode = mode;
    }

    protected override void OnInitialized()
    {
        // load devices
        // load system serial ports
        // string[] s_ports = SerialPort.GetPortNames();
        // serial_port_items.Add(new SelectedItem("关闭", "关闭"));
        // serial_port_items.Add(new SelectedItem("虚拟接口-1", "虚拟接口-1"));
        // serial_port_items.Add(new SelectedItem("虚拟接口-2", "虚拟接口-2"));
        // foreach (string s in s_ports)
        // {
        //     serial_port_items.Add(new SelectedItem(s, s));
        // }
        serial_port_items = GetSerialPortsList();

        // load monitor mode
        // load monitor ports
        MonModeChanged("");
        M0ModeChanged("");
        Cat1ModeChanged("");

        base.OnInitialized();
    }

    public void Dispose()
    {
        StopBleScan();
    }

    private Task OnM0PortItemChanged(int index, SelectedItem item)
    {
        emu_cfg.m0_port[index] = item.Value;
        // StateHasChanged();
        return Task.CompletedTask;
    }
    private Task OnCat1PortItemChanged(int index, SelectedItem item)
    {
        emu_cfg.cat1_port[index] = item.Value;
        // StateHasChanged();
        return Task.CompletedTask;
    }
    public void OnCloseClick()
    {
        option.CloseDialogAsync();
    }
    private void OnSaveClick()
    {
        string jsonString = JsonSerializer.Serialize(emu_cfg);
        File.WriteAllText(@".\app\zq_simu.config", jsonString);
        // DevProfiles.Reload(emu_cfg.device);
        Microsoft.Web.WebView2.Core.CoreWebView2? view = blazor_webview.get_webview();
        if(view != null)
            view.Reload();
        option.CloseDialogAsync();
    }
}
